#ifndef __SJA1000_H
#define __SJA1000_H

#include <asm/types.h>

/* Common Registers address allocation */
#define COMM_BUS_TIMING0   0x06
#define COMM_BUS_TIMING1   0x07
#define COMM_OUTPUT_CTRL   0x08
#define COMM_CLK_DIV       0x1f

/* Common Clock Divider Register */
#define CLK_DIV_CD         0
#define CLK_DIV_CLK_OFF    3
#define CLK_DIV_RXINTEN    5
#define CLK_DIV_CBP        6
#define CLK_DIV_CAN_MODE   7
// Initial values
#define CD_FREQ            (0x0 << CLK_DIV_CD)           /* fosc/2 */
#define CD_CLK_OFF         (0x1 << CLK_DIV_CLK_OFF)      /* disable external CLKOUT */
#define CD_CLK_ON          (0x0 << CLK_DIV_CLK_OFF)      /* enable external CLKOUT */
#define CD_RXINTEN         (0x0 << CLK_DIV_RXINTEN)
#define CD_CBP             (0x1 << CLK_DIV_CBP)
#define CD_MODE_BASIC      (0x0 << CLK_DIV_CAN_MODE)     /* BasicCAN mode */
#define CD_MODE_PELI       (0x1 << CLK_DIV_CAN_MODE)     /* PeliCAN mode */

/* Common Output Control Register */
#define OUTPUT_CTRL_MODE   0
#define OUTPUT_CTRL_POL0   2
#define OUTPUT_CTRL_TN0    3
#define OUTPUT_CTRL_TP0    4
#define OUTPUT_CTRL_POL1   5
#define OUTPUT_CTRL_TN1    6
#define OUTPUT_CTRL_TP1    7
// Initial values
#define OC_MODE            (0x2 << OUTPUT_CTRL_MODE)
#define OC_POL0            (0x0 << OUTPUT_CTRL_POL0)
#define OC_TN0             (0x1 << OUTPUT_CTRL_TN0)
#define OC_TP0             (0x1 << OUTPUT_CTRL_TP0)
#define OC_POL1            (0x0 << OUTPUT_CTRL_POL1)
#define OC_TN1             (0x0 << OUTPUT_CTRL_TN1)
#define OC_TP1             (0x0 << OUTPUT_CTRL_TP1)

/* Bus Timing Register 0 */
#define BUS_TIMING0_BRP    0
#define BUS_TIMING0_SJW    6
// Initial values
#define BT0_BRP            (0x4 << BUS_TIMING0_BRP)
#define BT0_SJW            (0x3 << BUS_TIMING0_SJW)

/* Bus Timing Register 1 */
#define BUS_TIMING1_TSEG1  0
#define BUS_TIMING1_TSEG2  4
#define BUS_TIMING1_SAM    7
// Initial values
#define BT1_TSEG1          (0x4 << BUS_TIMING1_TSEG1)
#define BT1_TSEG2          (0x3 << BUS_TIMING1_TSEG2)
#define BT1_SAM            (0x0 << BUS_TIMING1_SAM)

/* BasicCAN address allocation */
#define BCAN_CTRL           0x00
#define BCAN_CMD            0x01
#define BCAN_STATUS         0x02
#define BCAN_INTR           0x03
#define BCAN_ACP_CODE       0x04
#define BCAN_ACP_MASK       0x05
#define BCAN_BUS_TIMING0    0x06
#define BCAN_BUS_TIMING1    0x07
#define BCAN_OUTPUT_CTRL    0x08
#define BCAN_TEST           0x09
#define BCAN_TX_ID1         0x0a
#define BCAN_TX_ID0         0x0b
#define BCAN_TX_DATA0       0x0c
#define BCAN_TX_DATA1       0x0d
#define BCAN_TX_DATA2       0x0e
#define BCAN_TX_DATA3       0x0f
#define BCAN_TX_DATA4       0x10
#define BCAN_TX_DATA5       0x11
#define BCAN_TX_DATA6       0x12
#define BCAN_TX_DATA7       0x13
#define BCAN_RX_ID1         0x14
#define BCAN_RX_ID0         0x15
#define BCAN_RX_DATA0       0x16
#define BCAN_RX_DATA1       0x17
#define BCAN_RX_DATA2       0x18
#define BCAN_RX_DATA3       0x19
#define BCAN_RX_DATA4       0x1a
#define BCAN_RX_DATA5       0x1b
#define BCAN_RX_DATA6       0x1c
#define BCAN_RX_DATA7       0x1d
#define BCAN_UNUSED         0x1e
#define BCAN_CLK_DIV        0x1f

/* PeliCAN address allocation */
#define PCAN_MODE           0x00
#define PCAN_CMD            0x01
#define PCAN_STATUS         0x02
#define PCAN_INTR           0x03
#define PCAN_INTR_EN        0x04
#define PCAN_RESERVED0      0x05
#define PCAN_BUS_TIMING0    0x06
#define PCAN_BUS_TIMING1    0x07
#define PCAN_OUTPUT_CTRL    0x08
#define PCAN_TEST           0x09
#define PCAN_RESERVED1      0x0a
#define PCAN_ARBIT_LOST_CAP 0x0b
#define PCAN_ERR_CODE_CAP   0x0c
#define PCAN_ERR_WARN_LIMIT 0x0d
#define PCAN_RX_ERR_COUNT   0x0e
#define PCAN_TX_ERR_COUNT   0x0f
#define PCAN_ACP_CODE0      0x10   /* Reset mode */
#define PCAN_ACP_CODE1      0x11   /* Reset mode */
#define PCAN_ACP_CODE2      0x12   /* Reset mode */
#define PCAN_ACP_CODE3      0x13   /* Reset mode */
#define PCAN_ACP_MASK0      0x14   /* Reset mode */
#define PCAN_ACP_MASK1      0x15   /* Reset mode */
#define PCAN_ACP_MASK2      0x16   /* Reset mode */
#define PCAN_ACP_MASK3      0x17   /* Reset mode */
#define PCAN_RESERVED2      0x18   /* Reset mode */
#define PCAN_RESERVED3      0x19   /* Reset mode */
#define PCAN_RESERVED4      0x1a   /* Reset mode */
#define PCAN_RESERVED5      0x1b   /* Reset mode */
#define PCAN_RESERVED6      0x1c   /* Reset mode */
#define PCAN_FRAME_INFO     0x10   /* Operating mode */

/* SFF frame format address allocation */
#define PCAN_SFF_ID1        0x11   /* Operating mode */
#define PCAN_SFF_ID2        0x12   /* Operating mode */
#define PCAN_SFF_DATA1      0x13   /* Operating mode */
#define PCAN_SFF_DATA2      0x14   /* Operating mode */
#define PCAN_SFF_DATA3      0x15   /* Operating mode */
#define PCAN_SFF_DATA4      0x16   /* Operating mode */
#define PCAN_SFF_DATA5      0x17   /* Operating mode */
#define PCAN_SFF_DATA6      0x18   /* Operating mode */
#define PCAN_SFF_DATA7      0x19   /* Operating mode */
#define PCAN_SFF_DATA8      0x1a   /* Operating mode */

/* EFF frame format address allocation */
#define PCAN_EFF_ID1        0x11   /* Operating mode */
#define PCAN_EFF_ID2        0x12   /* Operating mode */
#define PCAN_EFF_ID3        0x13   /* Operating mode */
#define PCAN_EFF_ID4        0x14   /* Operating mode */
#define PCAN_EFF_DATA1      0x15   /* Operating mode */
#define PCAN_EFF_DATA2      0x16   /* Operating mode */
#define PCAN_EFF_DATA3      0x17   /* Operating mode */
#define PCAN_EFF_DATA4      0x18   /* Operating mode */
#define PCAN_EFF_DATA5      0x19   /* Operating mode */
#define PCAN_EFF_DATA6      0x1a   /* Operating mode */
#define PCAN_EFF_DATA7      0x1b   /* Operating mode */
#define PCAN_EFF_DATA8      0x1c   /* Operating mode */

#define PCAN_RX_MSG_COUNT   0x1d
#define PCAN_RX_BUF_ADDR    0x1e
#define PCAN_CLK_DIV        0x1f

/* BasicCAN Control Register */
#define BCAN_CTRL_RR        (0x01 << 0)   /* Reset Request */
#define BCAN_CTRL_RIE       (0x01 << 1)   /* Receive Interrupt Enable */
#define BCAN_CTRL_TIE       (0x01 << 2)   /* Transmit Interrupt Enable */
#define BCAN_CTRL_EIE       (0x01 << 3)   /* Error Interrupt Enable */
#define BCAN_CTRL_OIE       (0x01 << 4)   /* Overrun Interrupt Enable */
// Initial values
#define RR_OPERATING_MODE   (0x0)
#define RR_RESET_MODE       (BCAN_CTRL_RR)

/* PeliCAN Mode Register */
#define PCAN_MODE_RM        (0x01 << 0)
#define PCAN_MODE_LOM       (0x01 << 1)
#define PCAN_MODE_STM       (0x01 << 2)
#define PCAN_MODE_AFM       (0x01 << 3)
#define PCAN_MODE_SM        (0x01 << 4)
// Initial values
#define RM_RESET            (PCAN_MODE_RM)
#define AFM_SINGLE          (PCAN_MODE_AFM)

/* PeliCAN Command Register */
#define PCAN_CMD_TR        (0x01 << 0)
#define PCAN_CMD_AT        (0x01 << 1)
#define PCAN_CMD_RRB       (0x01 << 2)
#define PCAN_CMD_CDO       (0x01 << 3)
#define PCAN_CMD_SRR       (0x01 << 4)

/* PeliCAN Status Register */
#define PCAN_STAT_RBS      (0x01 << 0)
#define PCAN_STAT_DOS      (0x01 << 1)
#define PCAN_STAT_TBS      (0x01 << 2)
#define PCAN_STAT_TCS      (0x01 << 3)
#define PCAN_STAT_RS       (0x01 << 4)
#define PCAN_STAT_TS       (0x01 << 5)
#define PCAN_STAT_ES       (0x01 << 6)
#define PCAN_STAT_BS       (0x01 << 7)

/* PeliCAN Interrupt Register */
#define PCAN_INTR_RI       (0x01 << 0)
#define PCAN_INTR_TI       (0x01 << 1)
#define PCAN_INTR_EI       (0x01 << 2)
#define PCAN_INTR_DOI      (0x01 << 3)
#define PCAN_INTR_WUI      (0x01 << 4)
#define PCAN_INTR_EPI      (0x01 << 5)
#define PCAN_INTR_ALI      (0x01 << 6)
#define PCAN_INTR_BEI      (0x01 << 7)

/* PeliCAN Interrupt Enable Register */
#define PCAN_INTR_RIE      0
#define PCAN_INTR_TIE      1
#define PCAN_INTR_EIE      2
#define PCAN_INTR_DOIE     3
#define PCAN_INTR_WUIE     4
#define PCAN_INTR_EPIE     5
#define PCAN_INTR_ALIE     6
#define PCAN_INTR_BEIE     7
// Initial values
#define INTR_RI_ENABLE     (0x1 << PCAN_INTR_RIE)
#define INTR_RI_DISABLE    (0x0 << PCAN_INTR_RIE)
#define INTR_TI_ENABLE     (0x1 << PCAN_INTR_TIE)
#define INTR_TI_DISABLE    (0x0 << PCAN_INTR_TIE)
#define INTR_EI_ENABLE     (0x1 << PCAN_INTR_EIE)
#define INTR_EI_DISABLE    (0x0 << PCAN_INTR_EIE)
#define INTR_DOI_ENABLE    (0x1 << PCAN_INTR_DOIE)
#define INTR_DOI_DISABLE   (0x0 << PCAN_INTR_DOIE)
#define INTR_WUI_ENABLE    (0x1 << PCAN_INTR_WUIE)
#define INTR_WUI_DISABLE   (0x0 << PCAN_INTR_WUIE)
#define INTR_EPI_ENABLE    (0x1 << PCAN_INTR_EPIE)
#define INTR_EPI_DISABLE   (0x0 << PCAN_INTR_EPIE)
#define INTR_ALI_ENABLE    (0x1 << PCAN_INTR_ALIE)
#define INTR_ALI_DISABLE   (0x0 << PCAN_INTR_ALIE)
#define INTR_BEI_ENABLE    (0x1 << PCAN_INTR_BEIE)
#define INTR_BEI_DISABLE   (0x0 << PCAN_INTR_BEIE)

/* PeliCAN Bus Timing 0 Register */
#define PCAN_BT0_BRP0      (0x01 << 0)
#define PCAN_BT0_BRP1      (0x01 << 1)
#define PCAN_BT0_BRP2      (0x01 << 2)
#define PCAN_BT0_BRP3      (0x01 << 3)
#define PCAN_BT0_BRP4      (0x01 << 4)
#define PCAN_BT0_BRP5      (0x01 << 5)
#define PCAN_BT0_SJW0      (0x01 << 6)
#define PCAN_BT0_SJW1      (0x01 << 7)

/* PeliCAN Bus Timing 1 Register */
#define PCAN_BT1_TSEG1_0   (0x01 << 0)
#define PCAN_BT1_TSEG1_1   (0x01 << 1)
#define PCAN_BT1_TSEG1_2   (0x01 << 2)
#define PCAN_BT1_TSEG1_3   (0x01 << 3)
#define PCAN_BT1_TSEG2_0   (0x01 << 4)
#define PCAN_BT1_TSEG2_1   (0x01 << 5)
#define PCAN_BT1_TSEG2_2   (0x01 << 6)
#define PCAN_BT1_SAM       (0x01 << 7)

/* PeliCAN Output Control Register */
#define PCAN_OC_OCMODE0    (0x01 << 0)
#define PCAN_OC_OCMODE1    (0x01 << 1)
#define PCAN_OC_OCPOL0     (0x01 << 2)
#define PCAN_OC_OCTN0      (0x01 << 3)
#define PCAN_OC_OCTP0      (0x01 << 4)
#define PCAN_OC_OCPOL1     (0x01 << 5)
#define PCAN_OC_OCTN1      (0x01 << 6)
#define PCAN_OC_OCTP1      (0x01 << 7)

typedef struct frame_info {
	u8 dlc:      4,   /* data length code */
     dontcare: 2,   /* don't care */
     rtr:      1,   /* remote transmission request */
     format:   1;   /* frame format 0:SFF 1:EFF */
} frame_info_t;

typedef struct
{
	u32 id;                  /* identifier */
  frame_info_t frm_info;   /* frame information */
  u8 data[8];              /* data */
  struct list_head list;
} CAN_PACKAGE;

#define ACCEPTANCE_MASK_ALL    0xffffffff

/* SJA1000 ioctl() */
#define SJAIOCTL_SET_BAUD         0x534A0
#define SJAIOCTL_ACCEPTCODE_STD   0x534A1
#define SJAIOCTL_ACCEPTMASK_STD   0x534A2
#define SJAIOCTL_ACCEPTCODE_EXT   0x534A3
#define SJAIOCTL_ACCEPTMASK_EXT   0x534A4

#endif
